﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Xss.Data
{
    public interface IAdoHolder : IDisposable
    {
        IDbConnection DbConnection { get; }
        IDbTransaction DbTransaction { get; }
        bool EnableTransaction { get; }
        object ExecuteTransaction(Func<IAdoSession, object> func);
    }

    public class AdoHolder : IAdoHolder
    {
        public AdoHolder(bool active)
        {
            _active = active;
        }

        public AdoHolder(bool active, IAdoSession session)
            : this(active)
        {
            Session = session;
        }

        IDbConnection _connection;
        IDbTransaction _transaction;
        bool _active;

        public IDbConnection DbConnection
        {
            get { return _connection; }
        }

        public IDbTransaction DbTransaction
        {
            get
            {
                if (_active && _transaction == null)
                {
                    _transaction = _connection.BeginTransaction();
                }
                return _transaction;
            }
        }

        public object ExecuteTransaction(Func<IAdoSession, object> func)
        {
            object result = null;

            if (EnableTransaction)
            {
                using (DbTransaction)
                {
                    try
                    {
                        result = func.Invoke(_session);
                        DbTransaction.Commit();

                    }
                    catch
                    {
                        DbTransaction.Rollback();
                    }
                    finally
                    {
                        _transaction = null;
                    }
                }
            }
            else
            {
                result = func.Invoke(_session);
            }

            return result;

        }

        public bool EnableTransaction
        {
            get { return _active; }
        }
                
        public void Dispose()
        {
            if (_connection != null && _connection.State != ConnectionState.Closed)
            {
                _connection.Close();
                _connection = null;
            }

            _transaction = null;
        }

        private IAdoSession _session;
        public IAdoSession Session
        {
            set
            {
                _session = value;
                if (_session != null)
                {
                    _connection = _session.DbProvider.CreateConnection();
                }
            }
        }
    }

}
